package com.example.sdtreader;

import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.InputType;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RadioGroup;
import android.widget.Spinner;

import com.example.Utils.*;
import com.sdtapi.jni.*;

public class MainActivity extends Activity {

    private static final int CHANGE_TEXT = 1;
    private static final int CLEAR_TEXT = 0;
    //private Context m_ctx;
    // USB
    private static UsbDeviceHelper g_usbHelp;
    // COM
    private static ComDeviceHelper g_comHelp;

    private  String sfzpath;

    //通讯类型
    private Spinner m_comType;
    // 波特率
    private Spinner m_comBaud;
    // 设备挂载路径
    private Spinner m_DevPath;
    // 是否读指纹
    private RadioGroup m_radioFig;
    // 滚动显示信息
    // private LinearLayout m_LinearLInfo;
    // private TextView m_tvInfo;
    private EditText m_editMsg;

    private int  m_DevFD;
    // 获取权限的shell 命令集合
    private Set<String> m_CmdString = new HashSet<String>();

    private Button btnOpenDev;
    private Button btnCloseDev;
    private Button btnReadeMoudleID;
    private Button btnReadIDCard;
    private Button btnStartReadThread;
    private Button btnStopReadThread;
    private ImageView m_imgview;

    private boolean mWorking = false;
    private Thread mThread;
    //
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 全屏显示
        requestWindowFeature(Window.FEATURE_NO_TITLE);// 无标题
        //设置窗体
        setContentView(R.layout.activity_main);

        // 获取USB权限,注册USB插拔
        g_usbHelp = new UsbDeviceHelper(this);
        //m_ctx = this.getApplicationContext();
        g_comHelp = new ComDeviceHelper();

        //初始化界面
        InitView();

        //获取参数
        ShowTips(1, "安卓版本:" + android.os.Build.VERSION.RELEASE);
        ShowTips(1, "ROOT:" + ShellCommandExecutor.isDeviceRooted());
        ShowTips(1, "SELinuxMode:" + ShellCommandExecutor.getSELinuxMode());
        sfzpath = this.getCacheDir().getAbsolutePath() + "/zp.bmp";
        //ShowTips(1, "Path:." + sfzpath);

    }

//    @Override
//    public boolean onCreateOptionsMenu(Menu menu) {
//        // Inflate the menu; this adds items to the action bar if it is present.
//        getMenuInflater().inflate(R.menu.main, menu);
//        return true;
//    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
//        if (id == R.id.action_settings) {
//            return true;
//        }
        return super.onOptionsItemSelected(item);
    }

    private void InitCmdList() {
        //su 获取设备外设权限
        m_CmdString.add("chmod 777 -R /dev/bus/usb/;");
        // 串口
        m_CmdString.add("chmod 777 -R /dev/ttyUSB*;");
        m_CmdString.add("chmod 777 -R /dev/ttyGS*;");
        m_CmdString.add("chmod 777 -R /dev/ttyS*;");
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case CHANGE_TEXT: {
                    if (m_editMsg.getText().length() >= 3 * 1024) {
                        m_editMsg.getText().clear();
                    }
                    String info = (String) msg.obj;
                    // 在这里可以进行UI操作
                    // m_tvInfo.setText(info);
                    // m_tvInfo.setTextColor(android.graphics.Color.GREEN);
                    // m_LinearLInfo.addView(m_tvInfo);

                    m_editMsg.getText().append(info + "\r\n");
                    //m_editMsg.setText(info);
                    break;
                }
                case CLEAR_TEXT:{
                    m_editMsg.getText().clear();
                    break;
                }
                default:
                    break;
            }
        }
    };
    private static boolean power_control2(boolean enable){
        try {
            BufferedWriter bufWriter = null;
            bufWriter = new BufferedWriter(new FileWriter("/sys/idcard/power"));
            if(enable)
                bufWriter.write("1");
            else
                bufWriter.write("0");
            bufWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    @Override
    public void onDestroy() {
        //power_control2(false);
        super.onDestroy();
    }
    private void ShowTips(int what, String info) {
        Message msg = new Message();
        msg.what = what;
        msg.obj = info;
        handler.sendMessageDelayed(msg, 2);
    }

    private void InitView() {
        m_comBaud = (Spinner) findViewById(R.id.ComBaud);
        m_comBaud.setSelection(4);// 115200
        m_radioFig = (RadioGroup) findViewById(R.id.radioGroupFig);
        m_radioFig.check(0);
        m_DevPath = (Spinner) findViewById(R.id.DevPath);

        m_imgview = (ImageView)findViewById(R.id.imgView);
        // 显示提示信息
        // m_LinearLInfo = (LinearLayout)findViewById(R.id.svShowInfo);
        // m_tvInfo = new TextView(m_ctx); //创建显示textview
        // m_tvInfo.setTextSize(10);
        m_editMsg = (EditText) findViewById(R.id.editMsg);
        //多行输入
        m_editMsg.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);
        m_editMsg.setGravity(Gravity.TOP);
        m_editMsg.setSingleLine(false);

        // 设置滚动条
        // m_editMsg.setHorizontalScrollBarEnabled(true);
        m_editMsg.setHorizontallyScrolling(false);//水平滚动
        m_editMsg.setKeyListener(null);// 禁止输入

        // 设置滚动条自动滚动
        m_editMsg.setMovementMethod(ScrollingMovementMethod.getInstance());
        m_editMsg.setSelection(m_editMsg.getText().length(), m_editMsg.getText().length());
        //m_editMsg.setSelection(0);

        //获取权限
        InitCmdList();

        List<String> comList = new ArrayList<String>();
        String[] arrayComPath = null;
        try {
            // 获取设备挂载路径
            arrayComPath = g_comHelp.getAllDevicesPath();
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
        int i = 0;
        String cmd;
        if (arrayComPath != null && arrayComPath.length > 0) {
            for (i = 0; i < arrayComPath.length; i++) {
                cmd = "chmod 777 " + arrayComPath[i] + ";";
                // 增加下拉列表
                m_CmdString.add(cmd);
                comList.add(arrayComPath[i]);
            }
        } else {
            // 默认串口路径
            comList.add("/dev/ttyS0");
        }
        // 获取权限
        ShellCommandExecutor.chmodShell(m_CmdString);
        // 为下拉列表定义一个适配器
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, comList);
        // 设置下拉列表下拉时的菜单样式
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // 将适配器添加到下拉列表上
        m_DevPath.setAdapter(adapter);

        m_comType=(Spinner)findViewById(R.id.ComType);
		/*
		ArrayAdapter<CharSequence> adapter1=ArrayAdapter.createFromResource(this, R.array.ListComType,android.R.layout.simple_spinner_item);
		adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		m_comType.setAdapter(adapter1);
		*/

        // 绑定函数
        btnOpenDev = (Button) findViewById(R.id.btnOpenDev);
        btnCloseDev = (Button) findViewById(R.id.btnCloseDev);
        btnReadeMoudleID = (Button) findViewById(R.id.btnReadeMoudleID);
        btnReadIDCard = (Button) findViewById(R.id.btnReadIDCard);


        btnStartReadThread = (Button) findViewById(R.id.btnStartReadThread);
        btnStopReadThread = (Button) findViewById(R.id.btnStopReadThread);
        // 匿名内部类
        /*
         * btnOpenDev.setOnClickListener(new View.OnClickListener() {
         *
         * @Override public void onClick(View arg0) { // TODO Auto-generated
         * method stub //Toast.makeText(MainActivity.this, "clicked",
         * Toast.LENGTH_LONG).show(); } });
         */
        // implements onClickListener
        btnOpenDev.setOnClickListener(new BtnOperate());
        btnCloseDev.setOnClickListener(new BtnOperate());
        btnReadeMoudleID.setOnClickListener(new BtnOperate());
        btnReadIDCard.setOnClickListener(new BtnOperate());
        btnStartReadThread.setOnClickListener(new BtnOperate());
        btnStopReadThread.setOnClickListener(new BtnOperate());

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SignActivity.class);
                startActivity(intent);
            }
        });

        //power_control2(true);
    }

    // 内部类会自动拷贝外部变量的引用,用 final 来让该引用不可改变
    // 内部类可以直接使用外部类的成员变量，包括私有修饰的。
    // 外部类不能直接使用内部类的成员；如果需要使用，需要先创建内部类的对象，才能使用内部类成员。
    class BtnOperate implements OnClickListener {
        /*
         * private Context context; public BtnOperate(Context ctx){ context =
         * ctx; }
         */
        @SuppressLint("NonConstantResourceId")
        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            switch (arg0.getId()) {
                case R.id.btnOpenDev:
                    btnOpenDevClicked(arg0);
                    break;
                case R.id.btnCloseDev:
                    btnCloseDevClicked(arg0);
                    break;
                case R.id.btnReadIDCard:
                    btnReadIDCardClicked(arg0);
                    break;
                case R.id.btnReadeMoudleID:
                    btnReadeMoudleIDClicked(arg0);
                    break;

                case R.id.btnStartReadThread:
                    btnStartReadThreadClicked(arg0);
                    break;

                case R.id.btnStopReadThread:
                    btnStopReadThreadClicked(arg0);
                    break;
            }
        }

        public void btnOpenDevClicked(View arg0) {
            //Toast.makeText(MainActivity.this, "clicked",Toast.LENGTH_LONG).show();
            int ret = 0;
            String strtype =  m_comType.getSelectedItem().toString();

            if(strtype.equals("COM")){
                int baud = Integer.valueOf(m_comBaud.getSelectedItem().toString());
                String strdevpath = m_DevPath.getSelectedItem().toString().trim();
                byte[] devPath = new byte[0];
                devPath = strdevpath.getBytes();
                ret = JNISDTReader._SDT_OpenComBypath(devPath,baud);
            }else{

                //USB
                m_DevFD = g_usbHelp.getUsbFileDescriptor(0x0400,0xC35A);
                if(m_DevFD <= 0){
                    m_DevFD = g_usbHelp.getUsbFileDescriptor(0x0483,0x5652);
                }
                if(m_DevFD<=0){
                    ShowTips(1,"获取设备描述符失败,return = " + m_DevFD);
                    return;
                }
                //获取设备SELinux运行模式是否为强制模式
                String mode = ShellCommandExecutor.getSELinuxMode();
                //强制模式，代表 SELinux 运作中，且已经正确的开始限制 domain/type 了

                if(mode.equals("Enforcing")){
                    String strdevpath = g_usbHelp.getUsbDevPath();
                    byte[] devPath = new byte[0];
                    devPath = strdevpath.getBytes();

                    ret = JNISDTReader._SDT_OpenUsbByPath(m_DevFD,devPath);
                    //ret = JNISDTReader._SDT_OpenPort(1001,1,devPath,m_DevFD);
                }else{
                    //root 情况下也可以通过fd打开设备
                    ret = JNISDTReader._SDT_OpenUsbByFD(m_DevFD);
                    //ret = JNISDTReader._SDT_OpenPort(1001,0,null,m_DevFD);
                }
            }
            if(ret == 0x90){
                ShowTips(1, "打开设备成功.");
                ret = JNISDTReader._SDT_GetSAMStatus();
                if(ret == 0x90){
                    ShowTips(1, "SAM_A 正常,返回值:" + ret);
                }else{
                    ShowTips(1, "自检失败,返回值:" + ret);
                }
            }else{
                ShowTips(1, "打开设备失败,返回值:." + ret);
            }
        }

        public void btnCloseDevClicked(View arg0) {
            int ret = JNISDTReader._SDT_ClosePort();
            if(ret == 0x90){
                ShowTips(1, "关闭设备成功.");
            }else{
                ShowTips(1, "关闭设备失败,返回值:." + ret);
            }
        }

        public void btnReadIDCardClicked(View arg0) {
            int flag = 0;
            //RadioButton radioButton = (RadioButton)findViewById(m_radioFig.getCheckedRadioButtonId());
            //radioButton.getText().toString();

            //读卡
            byte[] pucManaInfo = new byte[8];
            byte[] pucManaMsg = new byte[8];
            byte[] pucCHMsg = new byte[260];
            byte[] pucPHMsg = new byte[1032];
            byte[] pucFPMsg = new byte[1032];
            int[] puiCHMsgLen = new int[2];
            int[] puiPHMsgLen = new int[2];
            int[] puiFPMsgLen = new int[2];
            int ret = 0;
            //寻卡
            //选卡
            //读卡
            //ret = JNISDTReader._SDT_StartFindIDCard(pucManaInfo);//4 个字节 0x00
            ret = JNISDTReader._SDT_SelectIDCard(pucManaMsg);    //8 个字节 0x00
            if(m_radioFig.getCheckedRadioButtonId() == R.id.radiobtnNoFig)
            {
                puiFPMsgLen[0] = 0;
                ret = JNISDTReader._SDT_ReadBaseMsg(pucCHMsg,puiCHMsgLen,//文字信息不得小于 256 字节
                        pucPHMsg,puiPHMsgLen);//相片信息不得小于 1024 字节
                Log.d("_SDT_ReadBaseMsg", "_SDT_ReadBaseMsg" + ret);
            }else{
                ret = JNISDTReader._SDT_ReadBaseFPMsg(pucCHMsg,puiCHMsgLen,pucPHMsg,puiPHMsgLen,
                        pucFPMsg,puiFPMsgLen);//指纹信息不得小于 1024 字节
            }
            if(ret != 0x90){
                ShowTips(1, "读取失败,错误码:" + ret);
                return;
            }else
            {
                //ShowTips(1, "读取成功:" + puiCHMsgLen[0] + ","  +puiFPMsgLen[0] + ","  + puiPHMsgLen[0]);
                //return;
            }

            IDCardMsg idinfo = new IDCardMsg();
            //解析文字数据
            ret = idinfo.ParseIDMsg(pucCHMsg,puiCHMsgLen[0]);
            if(ret != 0){
                ShowTips(1, "文字信息解析失败." + ret);
                return;
            }
            ShowTips(0, "");
            //显示信息
            String chmsg;
            if(idinfo.getIDType().equals("I") || idinfo.getIDType().equals("Y")){
                //2017版外国人永久居留证 新版外国人永久居留证
                chmsg = idinfo.getEngName() + "|" + idinfo.getSex() + "|" + idinfo.getID() + "|"
                        + idinfo.getNationality()+ "|"  + idinfo.getName() + "|" + idinfo.getStartDate() + "|"
                        + idinfo.getEndDate() + "|" + idinfo.getBirthday() + "|" +idinfo.getSignNum()+ "|"
                        + idinfo.getIssue() + "|" + idinfo.getReverse() + "|" + idinfo.getIDNum() + "|" + idinfo.getNationalityCode() +"|";
            }else if(idinfo.getIDType().equals("J")){
                //港澳台
                chmsg = idinfo.getName() + "|" + idinfo.getSex() + "|"
                        + idinfo.getBirthday() + "|" + idinfo.getAddr()+ "|"  + idinfo.getID() + "|"
                        + idinfo.getIssue() + "|" + idinfo.getStartDate() + idinfo.getEndDate() + "|" + idinfo.getPassID() + "|"
                        + idinfo.getSignNum() +  "|" + idinfo.getReverse();
            }else{
                //身份证
                chmsg = idinfo.getName() + "|" + idinfo.getSex() + "|"  + idinfo.getNation() + "|"
                        + idinfo.getBirthday() + "|" + idinfo.getAddr()+ "|"  + idinfo.getID() + "|"
                        + idinfo.getIssue() + "|" + idinfo.getStartDate() +  "|"  +idinfo.getEndDate() + "|" + idinfo.getReverse();
            }
            ShowTips(1, "文字信息:" + chmsg);
            if(puiFPMsgLen[0] > 0){
                String fpinfo = idinfo.ParseIDFpMsg(pucFPMsg,puiFPMsgLen[0]);
                ShowTips(1, "指纹信息:" + fpinfo);
            }

            //解析照片信息
            idinfo.setZpPath(sfzpath);
            ret = idinfo.ParseIDPHMsg(pucPHMsg,puiPHMsgLen[0]);
            if(ret != 1){
                ShowTips(1, "身份证解码失败." + ret);
            }
            else{
                //m_imgview.setImageResource(R.drawable.*);//前景
                //m_imgview.setBackgroundResource(R.drawable.*);//背景
                m_imgview.setScaleType(ScaleType.CENTER_INSIDE);//按比例缩放图片，使得图片长 (宽)的小于等于视图的相应维度
                //路径
                //m_imgview.setImageURI(Uri.fromFile(new File(idinfo.getZpPath())));

                //流转化成Bitmap对象
                m_imgview.setImageBitmap(getLoacalBitmap(idinfo.getZpPath()));

                ShowTips(1, "身份证解码成功,保存路径：" + idinfo.getZpPath());

            }

        }

        /**
         * 加载本地图片
         * @param url
         * @return
         */
        public  Bitmap getLoacalBitmap(String url) {
            try {
                FileInputStream fis = new FileInputStream(url);
                return BitmapFactory.decodeStream(fis);  ///把流转化为Bitmap图片

            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return null;
            }
        }

        public void btnReadeMoudleIDClicked(View arg0) {
            int ret = JNISDTReader._SDT_GetSAMStatus();
            if(ret == 0x90){
                //ShowTips(1, "SAM卡状态成功.");
                byte[]  mId = new byte[16];
                ret = JNISDTReader._SDT_GetSAMID(mId);
                if(ret == 0x90){
                    ShowTips(1, "模块ID:" + IDCardMsg.bytesToHexString(mId,16));
                }else{
                    ShowTips(1, "获取模块ID失败,返回值:." + ret);
                }

            }else{
                ShowTips(1, "获取SAM状态异常,返回值:." + ret);
            }
        }
        public void start() {
            mWorking = true;
            if (mThread != null && mThread.isAlive()) {
                ShowTips(1, "start: thread is alive");
            } else {
                mThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        int time = 100;//350;//
                        byte[] pucManaInfo = new byte[8];
                        byte[] pucManaMsg = new byte[8];
                        byte[] pucCHMsg = new byte[260];
                        byte[] pucPHMsg = new byte[1032];
                        byte[] pucFPMsg = new byte[1032];
                        int[] puiCHMsgLen = new int[2];
                        int[] puiPHMsgLen = new int[2];
                        int[] puiFPMsgLen = new int[2];
                        int ret = 0;
                        int count = 0,success = 0;

                        //PROCESSING
                        while (mWorking) {
                            try {
                                count++;
                                //寻卡
                                //选卡
                                //读卡
                                Date curDate = new Date(System.currentTimeMillis());
                                ret = JNISDTReader._SDT_StartFindIDCard(pucManaInfo);//4 个字节 0x00
                                ret = JNISDTReader._SDT_SelectIDCard(pucManaMsg);    //8 个字节 0x00
                                if(m_radioFig.getCheckedRadioButtonId() == R.id.radiobtnNoFig)
                                {
                                    puiFPMsgLen[0] = 0;
                                    ret = JNISDTReader._SDT_ReadBaseMsg(pucCHMsg,puiCHMsgLen,//文字信息不得小于 256 字节
                                            pucPHMsg,puiPHMsgLen);//相片信息不得小于 1024 字节
                                    Log.d("_SDT_ReadBaseMsg", "_SDT_ReadBaseMsg" + ret);
                                }else{
                                    ret = JNISDTReader._SDT_ReadBaseFPMsg(pucCHMsg,puiCHMsgLen,pucPHMsg,puiPHMsgLen,
                                            pucFPMsg,puiFPMsgLen);//指纹信息不得小于 1024 字节
                                }
                                Date endDate = new Date(System.currentTimeMillis());
                                long diff = endDate.getTime() - curDate.getTime();
                                if(ret != 0x90){
                                    ShowTips(1, "读取失败,错误码:" + ret + ",总次数:" + count + ",成功次数:" + success);
                                }else
                                {
                                    success++;
                                    ShowTips(1, "读取成功:" + ",总次数:" + count + ",成功次数:" + success + ",读卡时间(ms):" + diff);
                                }
                                Thread.sleep(time);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                });
                mThread.start();
            }
        }
        public void stop() {
            if (mWorking) {
                mWorking = false;
            }
        }
        public void btnStartReadThreadClicked(View arg0) {
            if (mWorking == false) {
                start();
            }
        }
        public void btnStopReadThreadClicked(View arg0) {
            stop();
        }

        public void handleClick(){
            Intent intent = new Intent(MainActivity.this, SignActivity.class);
            startActivity(intent);
        }
    }
}
